﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Tulde.WindowsPhone.Music.Mp3Tunes;
using System.Collections.Generic;
using Tulde.WindowsPhone.Music.ViewModel;

namespace Tulde.WindowsPhone.Music
{
    /// <summary>
    /// Using the MediaAPI provided by Mp3Tunes.com, retrieves data elements from a user's locker.  All data results are
    /// currently returned in JSON format.
    /// 
    /// To use this API, you must have a valid locker account with a partner token and username/password.
    /// </summary>
    public class Mp3TunesMusicService : IMusicService
    {

        #region IMusicService Members
        /// <summary>
        /// Enumerates all artists existing in a locker.
        /// <example>
        /// <![CDATA[
        /// No need to call this.Dispatch because we are already executing on the UI Thread.
        /// instance.EnumerateArtists( result=> {
        ///      this.myDataBoundControl.DataContext = result.ArtistList;
        /// } );
        /// 
        /// ]]>
        /// 
        /// </example>
        /// </summary>
        /// <param name="callback">Callback databinding lambda</param>
        public void EnumerateArtists(Action<ArtistCollection> callback)
        {
            LockerDataService<ArtistCollection> dataService = new LockerDataService<ArtistCollection>();
            Uri uri = dataService.CreateServiceEndpoint(LockerDataOperations.lockerData,
                new DataServiceParameters
                {

                    ServiceType = ServiceTypes.artist,
                    MiniData=false
                }
               );
            dataService.InvokeAsynch<ArtistCollection>(uri, callback);

        }
        /// <summary>
        /// Enumerates all albums existing in a locker.
        /// <example>
        /// <![CDATA[
        /// No need to call this.Dispatch because we are already executing on the UI Thread.
        /// instance.EnumerateAlbums( result=> {
        ///      this.myDataBoundControl.DataContext = result.albumList;
        /// } );
        /// 
        /// ]]>
        /// 
        /// </example>
        /// </summary>
        /// <param name="callback">Callback databinding lambda</param>
        public void EnumerateAlbums(Action<AlbumCollection> callback)
        {
            LockerDataService<AlbumCollection> dataService = new LockerDataService<AlbumCollection>();
            Uri uri = dataService.CreateServiceEndpoint(LockerDataOperations.lockerData,
                new DataServiceParameters
                {

                    ServiceType = ServiceTypes.album
                }
               );
            dataService.InvokeAsynch<AlbumCollection>(uri, callback);
        }
        /// <summary>
        /// Enumerates all tracks existing in a locker.
        /// <example>
        /// <![CDATA[
        /// No need to call this.Dispatch because we are already executing on the UI Thread.
        /// instance.EnumerateTracks( result=> {
        ///      this.myDataBoundControl.DataContext = result.TrackList;
        /// } );
        /// 
        /// ]]>
        /// 
        /// </example>
        /// </summary>
        /// <param name="callback">Callback databinding lambda</param>
        public void EnumerateTracks(Action<TrackCollection> callback)
        {
            LockerDataService<TrackCollection> dataService = new LockerDataService<TrackCollection>();
            Uri uri = dataService.CreateServiceEndpoint(LockerDataOperations.lockerData,
                new DataServiceParameters
                {

                    ServiceType = ServiceTypes.track,
                    MiniData = false

                }
               );
            dataService.InvokeAsynch<TrackCollection>(uri, callback);
        }
        /// <summary>
        /// Enumerates all videos existing in a locker.
        /// <example>
        /// <![CDATA[
        /// No need to call this.Dispatch because we are already executing on the UI Thread.
        /// instance.EnumerateTracks( result=> {
        ///      this.myDataBoundControl.DataContext = result.TrackList;
        /// } );
        /// 
        /// ]]>
        /// 
        /// </example>
        /// </summary>
        /// <param name="callback">Callback databinding lambda</param>
        public void EnumerateVideos(Action<TrackCollection> callback)
        {
            LockerDataService<TrackCollection> dataService = new LockerDataService<TrackCollection>();
            Uri uri = dataService.CreateServiceEndpoint(LockerDataOperations.lockerData,
                new DataServiceParameters
                {

                    ServiceType = ServiceTypes.video,
                    MiniData = false

                }
               );
            dataService.InvokeAsynch<TrackCollection>(uri, callback);
        }
        /// <summary>
        /// Enumerates all playlists existing in a locker.
        /// <example>
        /// <![CDATA[
        /// No need to call this.Dispatch because we are already executing on the UI Thread.
        /// instance.EnumeratePlaylists( result=> {
        ///      this.myDataBoundControl.DataContext = result.PlaylistList;
        /// } );
        /// 
        /// ]]>
        /// 
        /// </example>
        /// </summary>
        /// <param name="callback">Callback databinding lambda</param>
        public void EnumeratePlaylists(Action<PlaylistCollection> callback)
        {
            LockerDataService<PlaylistCollection> dataService = new LockerDataService<PlaylistCollection>();
            Uri uri = dataService.CreateServiceEndpoint(LockerDataOperations.lockerData,
                new DataServiceParameters
                {

                    ServiceType = ServiceTypes.playlist
                }
               );
            dataService.InvokeAsynch<PlaylistCollection>(uri, callback);
        }
        /// <summary>
        /// Search for artists given a search pattern.
        /// </summary>
        /// <param name="pattern"></param>
        /// <param name="callback"></param>
        public void SearchArtists(string pattern, Action<SearchResults> callback)
        {
            LockerSearchDataService<SearchResults> dataService = new LockerSearchDataService<SearchResults>();
            Uri uri = dataService.CreateServiceEndpoint(LockerDataOperations.lockerSearch,
                new DataServiceSearchParameters
                {

                    SearchPattern = pattern,
                    ServiceType = ServiceTypes.artist

                }
               );
            dataService.InvokeAsynch<SearchResults>(uri, callback);
        }
        /// <summary>
        /// Search for albums given a search pattern.
        /// </summary>
        /// <param name="pattern"></param>
        /// <param name="callback"></param>
        public void SearchAlbums(string pattern, Action<SearchResults> callback)
        {
            LockerSearchDataService<SearchResults> dataService = new LockerSearchDataService<SearchResults>();
            Uri uri = dataService.CreateServiceEndpoint(LockerDataOperations.lockerSearch,
                new DataServiceSearchParameters
                {

                    SearchPattern = pattern,
                    ServiceType = ServiceTypes.album

                }
               );
            dataService.InvokeAsynch<SearchResults>(uri, callback);
        }
        /// <summary>
        /// Search for tracks given a search pattern
        /// </summary>
        /// <param name="pattern"></param>
        /// <param name="callback"></param>
        public void SearchTracks(string pattern, Action<SearchResults> callback)
        {
            LockerSearchDataService<SearchResults> dataService = new LockerSearchDataService<SearchResults>();
            Uri uri = dataService.CreateServiceEndpoint(LockerDataOperations.lockerSearch,
                new DataServiceSearchParameters
                {

                    SearchPattern = pattern,
                    ServiceType = ServiceTypes.track,
                    MiniData = false

                }
               );
            dataService.InvokeAsynch<SearchResults>(uri, callback);
        }
        /// <summary>
        /// Returns a list of all albums for a given artist.
        /// </summary>
        /// <param name="artist"></param>
        /// <param name="callback"></param>
        public void GetArtistAlbums(ViewModel.Artist artist, Action<AlbumCollection> callback)
        {
            System.Net.WebClient client = new WebClient();
            LockerDataService<AlbumCollection> dataService = new LockerDataService<AlbumCollection>();
            Uri url = dataService.CreateServiceEndpoint(LockerDataOperations.lockerData, new DataServiceParameters
            {
                ServiceType = ServiceTypes.album,
                ArtistServiceKey = artist.ArtistId
            });

            dataService.InvokeAsynch<AlbumCollection>(url, callback);
        }
        /// <summary>
        /// Returns all tracks for a given album.
        /// </summary>
        /// <param name="album">The album  for which to find tracks.</param>
        /// <param name="callback"></param>
        public void GetAlbumTracks(ViewModel.Album album, Action<TrackCollection> callback)
        {
            System.Net.WebClient client = new WebClient();
            LockerDataService<TrackCollection> dataService = new LockerDataService<TrackCollection>();
            Uri url = dataService.CreateServiceEndpoint(LockerDataOperations.lockerData, new DataServiceParameters
            {
                ServiceType = ServiceTypes.track,
                AlbumServiceKey = album.AlbumId
            });
            dataService.InvokeAsynch<TrackCollection>(url, callback);
        }


        /// <summary>
        /// Authenticate a user 
        /// </summary>
        /// <param name="credentials"></param>
        /// <param name="callback"></param>
        public void Authenticate(ICredentials credentials, Action<ViewModel.AuthenticationToken> callback)
        {
            SecurityProvider.SetCredentials(credentials);
            AuthenticationService s = new AuthenticationService();
          
            Uri url = s.CreateServiceEndpoint(AuthenticationOperations.login, new AuthenticationServiceParameters
            {
                UserName = SecurityProvider.Credentials.UserName,
                Password = SecurityProvider.Credentials.Password
            });
            s.InvokeAsynch<AuthenticationToken>(url, callback);

        }
        public void GetPlaylist(Playlist playlist, Action<TrackCollection> callback)
        {
            System.Net.WebClient client = new WebClient();
            LockerDataService<TrackCollection> dataService = new LockerDataService<TrackCollection>();
            Uri url = dataService.CreateServiceEndpoint(LockerDataOperations.lockerData, new DataServiceParameters
            {
                ServiceType = ServiceTypes.track,
                PlaylistServiceKey = playlist.PlaylistId
            });
            dataService.InvokeAsynch<TrackCollection>(url, callback);
        }

        public void GetContinousDataStream(Track track, Action<byte[]> callback)
        {

        }
        #endregion


    }
}
